import Buff from '@/Buff';
import BuffUtil from '@/BuffUtil';

declare global {
    /**
     * 天赋技能配置数据模型
     */
    interface TalentConfigModel {
        id: string;
        name: string;
        art: string;
        desc: string;
        /* 未觉醒时的buff数据 */
        buffType: AppBuffType;
        /** 觉醒时的buff数据 */
        buffTypePlus: AppBuffType;
    }

    type TalentPlusData = { prevBuff: Buff; newBuff: Buff };

    type TalentCallback<T extends TalentBase = TalentBase, D extends TalentPlusData = TalentPlusData> = (u: unit, talent: T, data?: D) => void;
}

/**
 * 天赋技能基类
 */
export default abstract class TalentBase {
    id: string;
    abilityName: string;
    art: string;
    desc: string;
    buffType: AppBuffType;
    buffTypePlus: AppBuffType;
    constructor(p?: TalentConfigModel) {
        if (p != null) {
            this.id = p.id;
            this.abilityName = p.name;
            this.art = p.art;
            this.desc = p.desc;
            this.buffType = p.buffType;
            this.buffTypePlus = p.buffTypePlus;
            BuffUtil.registerBuffType(this.buffType);
            BuffUtil.registerBuffType(this.buffTypePlus);
        }
    }

    private _addTalentListeners: TalentCallback[] = [];
    /**
     * 为天赋添加 添加监听器
     * @param cb 监听器
     */
    onAddTalent(cb: TalentCallback) {
        this._addTalentListeners.push(cb);
    }
    /**
     * 为目标单位添加天赋技能
     * @param u 目标单位
     */
    addTalent(u: unit) {
        BuffUtil.addBuff(u, this.buffType.id, u);
        for (let cb of this._addTalentListeners) {
            cb.call(this, u, this);
        }
    }

    private _addTalentPlusListeners: TalentCallback[] = [];
    /**
     * 为天赋觉醒 添加监听器
     * @param cb 监听器
     */
    onAddTalentPlus(cb: TalentCallback) {
        this._addTalentPlusListeners.push(cb);
    }
    /**
     * 为目标单位觉醒天赋技能
     * @param u 目标单位
     */
    addTalentPlus(u: unit) {
        let prevBuff = BuffUtil.getUnitBuff(u, this.buffType.id);
        let newBuff = BuffUtil.addBuff(u, this.buffTypePlus.id, u);
        for (let cb of this._addTalentPlusListeners) {
            cb.call(this, u, this, { prevBuff, newBuff });
        }
        BuffUtil.clearUnitBuff(u, this.buffType.id);
    }

    /**
     * 对天赋的配置进行更新
     * @param cfg 配置数据
     */
    setTalentConfig(cfg: TalentConfigModel) {
        this.id = cfg.id;
        this.abilityName = cfg.name;
        this.art = cfg.art;
        this.desc = cfg.desc;
        this.buffType = cfg.buffType;
        this.buffTypePlus = cfg.buffTypePlus;
        BuffUtil.registerBuffType(this.buffType);
        BuffUtil.registerBuffType(this.buffTypePlus);
    }

    /**
     * 判断天赋是否失效
     * @param u 目标单位
     * @returns
     */
    talentUnEffect(u: unit) {
        let normal = BuffUtil.hasUnitBuff(u, this.buffType.id);
        let plus = BuffUtil.hasUnitBuff(u, this.buffTypePlus.id);
        return {
            unEffect: !normal && !plus,
            normal,
            plus,
        };
    }
}
